package com.github.wxiaoqi.security.crm.core.biz;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.http.util.TextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.github.wxiaoqi.security.common.crm.request.SendSMSRequest;
import com.github.wxiaoqi.security.common.crm.request.ValidateSMSRequest;
import com.github.wxiaoqi.security.common.msg.Constant;
import com.github.wxiaoqi.security.common.msg.ResponseCode;
import com.github.wxiaoqi.security.common.msg.SmsType;
import com.github.wxiaoqi.security.common.util.EntityUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 短信公共服务类
 * @author centerroot
 * @time 创建时间:2018年9月8日上午11:26:14
 * @description
 */
@Slf4j
@Service
public class SMSBiz {
	
	@Autowired
    private RedisTemplate<String, Object> redisTemplate;
	
	// 产品名称:云通信短信API产品,开发者无需替换
	private static final String product = "Dysmsapi";
    // 产品域名,开发者无需替换
	private static final String domain = "dysmsapi.aliyuncs.com";
	private char mapTable[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
	// 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
	@Value("${aliyun.sms.accessKeyId}")
	private String accessKeyId;
	@Value("${aliyun.sms.accessKeySecret}")
	private String accessKeySecret;
	// 潍坊市云支付
	@Value("${aliyun.sms.signName.icloudpay}")
    private String signNameIcloudpay;
	// 注册短信模板
	@Value("${aliyun.sms.template.register}")
    private String templateRegister;
	// 设置有效期
	@Value("${aliyun.sms.validityPeriod}")
    private Integer validityPeriod;
    
    
	/**
	 * 发送短信验证码
	 * @author centerroot
	 * @time 创建时间:2018年9月8日下午2:23:24
	 * @param SendSMSRequest
	 * @return
	 */
	public Map<String, Object> sendSmsCode(SendSMSRequest sendSMSRequest){
		log.debug("【发送短信】--请求参数：",EntityUtils.beanToMap(sendSMSRequest));
		Map<String, Object> respMap = new HashMap<String, Object>();
		Map<String, Object> sendMap = new HashMap<String, Object>();
		Map<String, String> smsParam = new HashMap<String, String>();
		String phone = sendSMSRequest.getPhone();
		String busType = sendSMSRequest.getBusType();
		sendMap.put("busType", busType);
		
		// 1、判断发送短信签名
		sendMap.put("signName", signNameIcloudpay);
		// 2、添加待发送号码
		sendMap.put("phone", phone);
		// 3、生成短信验证码
		String smsCode = generate();
		smsParam.put("code", smsCode);
		sendMap.put("smsParam", smsParam);
		// 4、获取短信模板
		sendMap = getTemplateCode(sendMap);
		// 5、发送短信验证码
		respMap = sendSms(sendMap);
		if (ResponseCode.OK.getCode().equals(respMap.get("code"))) {
			// 6、缓存验证码 设置验证码失效时间
			redisTemplate.opsForValue().set(Constant.SEND_CODE + phone + "_" + smsCode, smsCode, validityPeriod, TimeUnit.MINUTES);//向redis里存入数据和设置缓存时间
		}
    	log.info("【发送短信】--响应参数：{}",respMap);
		return respMap;
	}
	
	/**
	 * 验证短信验证码
	 * @author centerroot
	 * @time 创建时间:2018年9月8日下午3:41:40
	 * @param validateSMSRequest
	 * @return
	 */
	public Map<String, Object> validateSmsCode(ValidateSMSRequest validateSMSRequest){
		log.debug("【验证短信验证码】--请求参数：",EntityUtils.beanToMap(validateSMSRequest));
		Map<String, Object> respMap = new HashMap<String, Object>();
		String phone = validateSMSRequest.getPhone();
		String code = validateSMSRequest.getCode();
		String redisCode = (String) redisTemplate.opsForValue().get(Constant.SEND_CODE + phone + "_" + code);//根据key获取缓存中的val
		if (null != redisCode) {
			respMap.put("code", ResponseCode.OK.getCode());
			respMap.put("msg", ResponseCode.OK.getMessage());
		} else {
			respMap.put("code", ResponseCode.SMS_CODE_MATCH_FAIL.getCode());
			respMap.put("msg", ResponseCode.SMS_CODE_MATCH_FAIL.getMessage());
		}
		

//		respMap.put("code", ResponseCode.OK.getCode());
//		respMap.put("msg", ResponseCode.OK.getMessage());
		
		
    	log.info("【验证短信验证码】--响应参数：{}",respMap);
		return respMap;
	}
	
	
	
	
	/**
	 * 请求阿里云平台短信接口公共方法
	 * @author centerroot
	 * @time 创建时间:2018年9月8日下午2:36:18
	 * @param sendMap
	 * @return
	 */
    public Map<String, Object> sendSms(Map<String, Object> sendMap){
    	log.info("请求阿里云短信平台请求参数：{}",sendMap);
    	Map<String, Object> respMap = new HashMap<String, Object>();
    	String phone = (String) sendMap.get("phone");
    	String signName = (String) sendMap.get("signName");
    	String templateCode = (String) sendMap.get("templateCode");
    	Map<String, String> smsParam = (Map<String, String>) sendMap.get("smsParam");

        //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        try {
	        //初始化acsClient,暂不支持region化
	        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
	        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
	        IAcsClient acsClient = new DefaultAcsClient(profile);
	
	        //组装请求对象-具体描述见控制台-文档部分内容
	        SendSmsRequest request = new SendSmsRequest();
	        //必填:待发送手机号
	        request.setPhoneNumbers(phone);
	        //必填:短信签名-可在短信控制台中找到
	        request.setSignName(signName);
	        //必填:短信模板-可在短信控制台中找到
	        request.setTemplateCode(templateCode);
	        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
	//        request.setTemplateParam("{\"name\":\"Tom\", \"code\":\"123\"}");
			StringBuilder sb = new StringBuilder();
			sb.append("{");
			for (Map.Entry<String, String> entry : smsParam.entrySet()) {
				if (!TextUtils.isEmpty(entry.getKey()) && !TextUtils.isEmpty(entry.getValue()))
					sb.append("\"").append(entry.getKey()).append("\":\"").append(entry.getValue()).append("\",");
			}
			sb.deleteCharAt(sb.length()-1);
			sb.append("}");
			log.info("【发送短信】模板中的变量替换JSON串：{}",sb.toString());
			request.setTemplateParam(sb.toString());
	
	        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
	        //request.setSmsUpExtendCode("90997");
	
	        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
	//        request.setOutId("yourOutId");
	
	        //hint 此处可能会抛出异常，注意catch
	        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
	        log.info("【发送短信】请求阿里云短信平台返回结果：{}",EntityUtils.beanToMap(sendSmsResponse));
	        if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
	        	// 请求成功
	        	respMap.put("code", ResponseCode.OK.getCode());
				respMap.put("msg", ResponseCode.OK.getMessage());
        	}else{
        		// 请求失败
        		respMap.put("code", ResponseCode.SMS_SEND_FAIL.getCode());
    			respMap.put("msg", ResponseCode.SMS_SEND_FAIL.getMessage());
        	}
	        
		} catch (ClientException e) {
			e.printStackTrace();
			respMap.put("code", ResponseCode.ABNORMAL_FIELDS.getCode());
			respMap.put("msg", ResponseCode.ABNORMAL_FIELDS.getMessage());
		}

        return respMap;
    }
    /**
	 * 生成6位数的验证码
	 * @return
	 */
	private String generate() {
		StringBuilder strEnsure = new StringBuilder();
		for (int i = 0; i < 6; ++i) {
			strEnsure.append(mapTable[(int) (mapTable.length * Math.random())]);
		}
		return strEnsure.toString();
	}
	/**
	 * 根据短信业务类型 设置短信模板
	 * @param busType
	 * @return
	 */
	private Map<String, Object> getTemplateCode(Map<String, Object> sendMap) {
        log.info("【发送短信】根据短信业务类型 设置短信模板请求参数：{}",sendMap);
		String busType = (String) sendMap.get("busType");
		if (busType.equals(SmsType.register.getCode())) {
			sendMap.put("templateCode", templateRegister);
		}
		return sendMap;
	}
	
//	public static void main(String[] args) {
//
//        //发短信
//        SendSmsResponse response = sendSms();
//    }
}